# -*- encoding: utf-8 -*-

# Copyright 2010 István Szentandrási
# <etude-music-player@googlegroups.com>

# This file is part of Etude.
#
# Etude is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as 
# published by the Free Software Foundation, either version 3 
# of the License, or (at your option) any later version.
#
# Etude is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with Etude. If not, see <http://www.gnu.org/licenses/>.

from . import _
import etude.plugins as ep
import etude.client as ec
from lastfm import LastFM, Scrobbler
import gtk, gobject
import time
import threading

DURATION_MIN_LIMIT = 30
DURATION_ACCEPT_LIMIT = 240


class AudioScrobbler(ep.PluginExtra):
    """
    AudioScrobbling plugin 
    """
    _short_name = "AudioScrobbler"
    _show_name = _("AudioScrobbler (LastFM)")
    _short_descr = ""
    _version = "0.1"
    _unique = "AudioScrobbler-0.1"     
    __author__ = "Szentandrási István"


    def __init__(self, control):
        ep.PluginExtra.__init__(self, control)
        lastfm = LastFM(self.config)
        self.scrobbler = Scrobbler()
        thread = threading.Thread(target=self.init_scrobbler, args=(lastfm,))
        thread.run()
        
        self.prev_info = ec.MediaInfo()
        self.prev_info['id'] = -1
        self.prev_timestamp = time.time()
        self.bind(self.control.client, 'e_playback_current_id',
                self.song_changed)
        self.bind_after(self.control.client, 'e_playback_status',
                self.status_changed)

    def init_scrobbler(self, lastfm):
        if not self.scrobbler.init_scrobbler(lastfm):
            gobject.timeout_add(100, self.control.unload_extra, self._unique)
            return

        self.login()


    def login(self, count = 0):
        st = self.scrobbler.login()
        if count == 3:
            ##try to connect three times after that disable scrobbling
            gobject.timeout_add(100, self.control.unload_extra, self._unique,
                    True, False)
            return 
        if not st[0]:
            print(st)
            gobject.timeout_add(5000*(count+1), self.login, count+1)
        return 

    def song_changed(self, client, song_id):
        prev_timestamp = self.prev_timestamp
        self.prev_timestamp = time.time()
        
        now_playing = False
        
        while 1:

            if not self.prev_info.has_key('id'):
                self.prev_info['id'] = -1
            
            if song_id == self.prev_info['id']:
                if song_id != -1: 
                    now_playing = True
                break
            prev_info = ec.MediaInfo(self.prev_info)
            
            if song_id == -1:
                self.prev_info = ec.MediaInfo()
                self.prev_info['id'] = -1
            else:
                self.prev_info = ec.MediaInfo(client.playback.current_info)
                now_playing = True
        
            try:
                duration = int(prev_info['duration'])/1000
            except:
                duration = 0
            if duration <= DURATION_MIN_LIMIT:
                break
            #we count the diff from the last started time (includes starting after
            #pause/stop, don't care how much was played before that
            diff = self.prev_timestamp - prev_timestamp
            if diff < min(duration/2, DURATION_ACCEPT_LIMIT):
                break

            artist, track, album, tracknr, url, track_id = prev_info.get_custom_info(
                    "{<artist>}|{<title>}|{<album>}|{<tracknr>}|{<url>}|{<track_id>}")

            if not (artist and track):
                break

            thread = threading.Thread(target=self.scrobbler.submit,
                    args=(artist,track),
                    kwargs={'album': album, 'tracknr': tracknr,
                        'length': duration, 'mbid': track_id})
            thread.run()
            #st = self.scrobbler.submit(artist, track, album = album, tracknr = tracknr,
            #        length = duration, mbid = track_id)
            #print('submit', st)
            break
        if now_playing:
            self.now_playing()
        return False


    def now_playing(self):
        pb = self.control.client.playback
        if (pb.status != ec.PB_PLAY):
            return False
        
        artist, track, album, tracknr, track_id = self.prev_info.get_custom_info(
                "{<artist>}|{<title>}|{<album>}|{<tracknr>}|{<track_id>}")
        try:
            duration = int(self.prev_info['duration'])/1000
        except:
            duration = 0

        if not (artist and track):
            return False
        thread = threading.Thread(target=self.scrobbler.now_playing,
                args=(artist, track, album, duration, tracknr, track_id))
        thread.run()
        #st = self.scrobbler.now_playing(artist, track, album, duration, tracknr, track_id)
        #print('now_playing', st)
        return False

    def status_changed(self, client, status):
        if status == ec.PB_STOP:
            self.song_changed(client, -1)
        elif status == ec.PB_PAUSE:
            try:
                song_id = self.prev_info['id']
            except KeyError:
                pass
            else:
                self.song_changed(client, song_id)
        elif status == ec.PB_PLAY:
            try:
                song_id = client.playback.current_info['id']
            except KeyError:
                pass
            else:
                self.song_changed(client, song_id)

    def show_preferences(self, parent):
        dialog = gtk.MessageDialog( parent,
                gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT,
                gtk.MESSAGE_OTHER,
                buttons=gtk.BUTTONS_OK_CANCEL
                )
        dialog.set_default_size(300, 200)
        dialog.set_markup("<b>"+_("AudioScrobbler settings")+"</b>")
        dialog.set_title(_("AudioScrobbler settings"))
        dialog.format_secondary_text(_("The currently used last.fm user account."\
                "Click reset to change/reset username. You will be then asked to allow "\
                "Etude to use that account."\
                "\n Once you clicked reset, the current active account will be disabled"))
        table = gtk.Table(rows = 1, columns = 3)
        table.attach(gtk.Label(_("Active account: ")), 0, 1, 0, 1, xoptions =0, yoptions = 0)
        try:
            label = gtk.Label("<b>"+self.scrobbler.last_fm.lfm_username+"</b>")
            label.set_use_markup(True)
            table.attach(label, 1, 2, 0, 1, 
                    xoptions = gtk.FILL| gtk.EXPAND, yoptions = 0)
        except AttributeError:
            pass

        tbutton = gtk.Button(_("Reset"))
        tbutton.connect('clicked', self.reset_lastfm, dialog)
        table.attach(tbutton, 2, 3, 0, 1, xoptions = 0, yoptions = 0)

        dialog.vbox.add(table)
        dialog.show_all()
        res = dialog.run()
        dialog.destroy()

    def reset_lastfm(self, button, dialog):
        dialog.destroy()
        self.scrobbler.last_fm.authenticate()
        self.login()

